<template>
  <div class="department-manage-container">
    <!-- 页面标题 + 操作栏 -->
    <div class="page-header">
      <el-breadcrumb separator="/" class="breadcrumb">
        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>部门管理</el-breadcrumb-item>
      </el-breadcrumb>

      <div class="operation-bar">
        <el-input
            v-model="searchValue"
            placeholder="请输入部门名称搜索"
            class="search-input"
            clearable
            @keyup.enter="handleSearch"
            style="width: 280px; height: 36px;"
        >
          <template #append>
            <el-button :icon="Search" @click="handleSearch" size="small" style="height: 100%; border-left: none;" />
          </template>
        </el-input>

        <el-button
            type="primary"
            @click="handleAddDepartment"
            icon="Plus"
            size="small"
            style="margin-left: 10px;">
          新增
        </el-button>
        <el-button
            type="warning"
            @click="toggleExpandAll"
            :icon="allExpanded ? Expand : Collapse"
            size="small"
            style="margin-left: 10px;"
        >
          {{ allExpanded ? '全部折叠' : '全部展开' }}
        </el-button>
      </div>
    </div>

    <!-- 部门表格 -->
    <el-card class="table-card" shadow="hover">
      <el-skeleton v-if="loading" row-count="6" :columns="5" border></el-skeleton>

      <el-table
          v-else
          :data="processedDepartmentList"
          style="width: 100%; font-size: 13px;"
          stripe
          border
          :header-cell-style="headerCellStyle"
          :cell-style="cellStyle"
          row-key="departmentId"
          :indent="36"
          tree-props="{ 
            children: 'children', 
            hasChildren: 'hasChildren',
            isLeaf: 'isLeaf'
          }"
          :expand-row-keys="expandRowKeys"
          @expand-change="handleExpandChange"
          size="mini"
          :expand-on-click-row="true"
      >
        <!-- 序号列 -->
        <el-table-column type="index" label="序号" width="60" align="center"></el-table-column>

        <!-- 部门名称 -->
        <el-table-column prop="departmentName" label="部门名称" min-width="200">
          <template #default="{ row, level }">
            <div class="dept-tree-wrapper" :style="{ paddingLeft: (level - 1) * 30 + 'px' }">
              <span class="dept-name">{{ row.departmentName }}</span>
            </div>
          </template>
        </el-table-column>

        <!-- 部门ID -->
        <el-table-column prop="departmentId" label="部门ID" width="120" align="center"></el-table-column>

        <!-- 父部门ID -->
        <el-table-column prop="parentDepartmentId" label="父部门ID" width="120" align="center">
          <template #default="{ row }">
            <span>{{ row.parentDepartmentId || '-' }}</span>
          </template>
        </el-table-column>

        <!-- 父部门名称 -->
        <el-table-column label="父部门名称" width="180" align="center">
          <template #default="{ row }">
            <span>{{ getParentDepartmentName(row.parentDepartmentId) || '无' }}</span>
          </template>
        </el-table-column>

        <!-- 创建时间 -->
        <el-table-column prop="createTime" label="创建时间" width="180" align="center">
          <template #default="{ row }">
            <span>{{ formatDate(row.createTime) }}</span>
          </template>
        </el-table-column>

        <!-- 操作 -->
        <el-table-column label="操作" min-width="220" align="center">
          <template #default="{ row }">
            <el-button
                type="text"
                size="mini"
                @click.stop="handleAddSubDepartment(row)"
                class="oper-btn add-btn"
            >
              <el-icon size="14"><Plus /></el-icon> 新增子部门
            </el-button>

            <el-button
                type="text"
                size="mini"
                @click.stop="editDepartment(row)"
                class="oper-btn edit-btn"
            >
              <el-icon size="14"><Edit /></el-icon> 编辑
            </el-button>

            <el-button
                type="text"
                size="mini"
                @click.stop="handleDeleteConfirm(row)"
                :disabled="hasChildren(row)"
                class="oper-btn delete-btn"
            >
              <el-icon size="14"><Delete /></el-icon> 删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div v-if="!loading && processedDepartmentList.length === 0" class="empty-tip">
        <el-empty description="暂无部门数据"></el-empty>
      </div>
    </el-card>

    <!-- 部门编辑/添加对话框 -->
    <el-dialog
        v-model="showDepartmentDialog"
        :title="dialogTitle"
        width="500px"
        :close-on-click-modal="false"
        :before-close="handleDialogClose"
        destroy-on-close
    >
      <el-form
          :model="deptForm"
          label-width="110px"
          class="dept-form"
          :rules="deptRules"
          ref="deptFormRef"
          size="mini"
      >
        <el-form-item label="部门ID" v-if="isEditMode" disabled>
          <el-input v-model="deptForm.departmentId" style="width: 100%;"></el-input>
        </el-form-item>

        <el-form-item label="部门名称" prop="departmentName">
          <el-input
              v-model="deptForm.departmentName"
              placeholder="请输入部门名称"
              maxlength="128"
              style="width: 100%;"
          ></el-input>
        </el-form-item>

        <el-form-item label="上级部门" prop="parentDepartmentId">
          <el-select
              v-model="deptForm.parentDepartmentId"
              placeholder="请选择上级部门"
              style="width: 100%;"
              :disabled="isSubDepartment"
              filterable
              clearable
          >
            <el-option
                value="0"
                label="顶级部门"
            ></el-option>
            <el-option
                v-for="dept in flatDepartmentList"
                :key="dept.departmentId"
                :value="dept.departmentId"
                :label="getDepartmentLevelLabel(dept)"
                :disabled="isEditMode && (dept.departmentId === deptForm.departmentId || isChildOf(deptForm.departmentId, dept.departmentId))"
            ></el-option>
          </el-select>
          <div class="form-tip">选择"顶级部门"创建一级部门</div>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button size="mini" @click="showDepartmentDialog = false">取消</el-button>
        <el-button size="mini" type="primary" @click="saveDepartment">确定</el-button>
      </template>
    </el-dialog>

    <!-- 删除确认对话框 -->
    <el-dialog
        v-model="showDeleteDialog"
        title="删除确认"
        width="350px"
        :close-on-click-modal="false"
        destroy-on-close
    >
      <div class="delete-tip">
        <el-icon size="24" style="color: #f56c6c;"><Warning /></el-icon>
        <p v-if="hasChildren(currentDepartment)">
          该部门包含 <span class="text-danger">{{ countChildDepartments(currentDepartment) }}</span> 个子部门，不允许直接删除！
          <br>请先删除所有子部门后重试。
        </p>
        <p v-else>
          确定要删除部门「<span class="text-primary">{{ currentDepartment?.departmentName }}</span>」吗？
        </p>
      </div>
      <template #footer>
        <el-button size="mini" @click="showDeleteDialog = false">取消</el-button>
        <el-button
            size="mini"
            type="danger"
            @click="deleteDepartment"
            :disabled="hasChildren(currentDepartment)"
        >
          确认删除
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, reactive, watch, computed, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Search, Plus, Edit, Delete, Expand, Collapse, Warning } from '@element-plus/icons-vue';
import axios from 'axios';

// 状态管理
const departmentList = ref([]); // 原始树形部门数据
const flatDepartmentList = ref([]); // 扁平部门列表
const processedDepartmentList = ref([]); // 处理后的部门列表
const loading = ref(false);
const searchValue = ref('');

// 树形表格状态
const expandRowKeys = ref([]);
const allExpanded = ref(false);

// 对话框状态
const showDepartmentDialog = ref(false);
const showDeleteDialog = ref(false);
const isEditMode = ref(false);
const isSubDepartment = ref(false);
const currentDepartment = ref(null);

// 表单引用与数据
const deptFormRef = ref(null);
const deptForm = reactive({
  departmentId: '',
  departmentName: '',
  parentDepartmentId: 0,
  createTime: null,
  updateTime: null
});

// 配置项
const headerCellStyle = {
  background: '#f8f9fa',
  color: '#333',
  fontWeight: 500,
  borderBottom: '1px solid #e9ecef'
};

const cellStyle = {
  color: '#666',
  borderBottom: '1px solid #f0f2f5'
};

// 表单验证规则
const deptRules = reactive({
  departmentName: [
    { required: true, message: '请输入部门名称', trigger: 'blur' },
    { max: 128, message: '部门名称长度不能超过128个字符', trigger: 'blur' }
  ]
});

// 对话框标题
const dialogTitle = computed(() => {
  if (isEditMode.value) return '编辑部门';
  if (isSubDepartment.value) return `新增【${currentDepartment.value?.departmentName}】子部门`;
  return '新增部门';
});

// 核心方法
/**
 * 初始化：加载部门数据
 */
const getAllDepartments = async () => {
  try {
    loading.value = true;
    const res = await axios.get('/api/department/get-all-departments');
    if (res.data.code === 200 && res.data.data) {
      // 接收原始树形数据
      departmentList.value = res.data.data;
      // 处理数据：补充hasChildren和isLeaf属性
      processedDepartmentList.value = processDepartmentTree(res.data.data);
      // 生成扁平部门列表
      flatDepartmentList.value = flattenDepartmentTree(res.data.data);
      // 初始化展开顶级部门
      await initExpandKeys();
    } else {
      ElMessage.error(res.data.msg || '获取部门列表失败');
    }
  } catch (error) {
    console.error('加载部门失败：', error);
    ElMessage.error('加载部门失败，请刷新页面重试');
  } finally {
    loading.value = false;
  }
};

/**
 * 处理部门树：补充hasChildren和isLeaf属性
 */
const processDepartmentTree = (departments) => {
  return departments.map(dept => {
    const children = dept.children || [];
    const processedChildren = processDepartmentTree(children);
    return {
      ...dept,
      children: processedChildren,
      hasChildren: processedChildren.length > 0,
      isLeaf: processedChildren.length === 0
    };
  });
};

/**
 * 树形部门转扁平列表
 */
const flattenDepartmentTree = (departments, result = []) => {
  departments.forEach(dept => {
    const deptCopy = { ...dept };
    delete deptCopy.children;
    result.push(deptCopy);
    if (dept.children && dept.children.length) {
      flattenDepartmentTree(dept.children, result);
    }
  });
  return result;
};

/**
 * 初始化展开的节点（展开所有顶级部门）
 */
const initExpandKeys = async () => {
  await nextTick();
  // 获取所有顶级部门ID（parentDepartmentId=0）
  const topLevelIds = processedDepartmentList.value
      .filter(dept => dept.parentDepartmentId === 0)
      .map(dept => dept.departmentId);
  expandRowKeys.value = [...topLevelIds];
  allExpanded.value = topLevelIds.length > 0;
};

/**
 * 搜索过滤
 */
const handleSearch = () => {
  const search = searchValue.value.trim().toLowerCase();
  if (!search) {
    processedDepartmentList.value = processDepartmentTree(departmentList.value);
    initExpandKeys();
    return;
  }

  // 树形过滤：保留匹配节点及所有父节点
  const filterTree = (departments) => {
    return departments
        .map(dept => {
          const children = filterTree(dept.children || []);
          const isMatch =
              dept.departmentName.toLowerCase().includes(search) ||
              children.length > 0;
          return isMatch ? { ...dept, children } : null;
        })
        .filter(dept => dept !== null);
  };

  processedDepartmentList.value = filterTree(departmentList.value);
  initExpandKeys();
};

/**
 * 切换全部展开/折叠
 */
const toggleExpandAll = () => {
  if (allExpanded.value) {
    expandRowKeys.value = [];
  } else {
    const getAllIds = (departments, ids = []) => {
      departments.forEach(dept => {
        ids.push(dept.departmentId);
        if (dept.children && dept.children.length) {
          getAllIds(dept.children, ids);
        }
      });
      return ids;
    };
    expandRowKeys.value = getAllIds(processedDepartmentList.value);
  }
  allExpanded.value = !allExpanded.value;
};

/**
 * 处理节点展开/折叠变化
 */
const handleExpandChange = (row, expanded) => {
  if (expanded) {
    expandRowKeys.value.push(row.departmentId);
  } else {
    expandRowKeys.value = expandRowKeys.value.filter(id => id !== row.departmentId);
  }
  const totalNodes = countAllNodes(processedDepartmentList.value);
  allExpanded.value = expandRowKeys.value.length === totalNodes;
};

/**
 * 计算所有节点总数
 */
const countAllNodes = (departments) => {
  let count = departments.length;
  departments.forEach(dept => {
    if (dept.children && dept.children.length) {
      count += countAllNodes(dept.children);
    }
  });
  return count;
};

/**
 * 获取父部门名称
 */
const getParentDepartmentName = (parentId) => {
  if (parentId === 0) return '';
  return flatDepartmentList.value.find(dept => dept.departmentId === parentId)?.departmentName;
};

/**
 * 获取部门层级标签
 */
const getDepartmentLevelLabel = (dept) => {
  const getParentLabel = (id, labels = []) => {
    const parent = flatDepartmentList.value.find(m => m.departmentId === id);
    if (parent) {
      labels.unshift(parent.departmentName);
      if (parent.parentDepartmentId !== 0) {
        getParentLabel(parent.parentDepartmentId, labels);
      }
    }
    return labels;
  };

  const labels = getParentLabel(dept.parentDepartmentId);
  labels.push(dept.departmentName);
  return labels.join(' > ');
};

/**
 * 检查是否为子部门关系
 */
const isChildOf = (parentId, childId) => {
  const findChild = (id) => {
    const dept = flatDepartmentList.value.find(m => m.departmentId === id);
    if (!dept) return false;
    return flatDepartmentList.value.some(m => m.parentDepartmentId === id && (m.departmentId === childId || findChild(m.departmentId)));
  };
  return findChild(parentId);
};

/**
 * 检查是否有子部门
 */
const hasChildren = (dept) => {
  if (!dept) return false;
  return (dept.children && dept.children.length > 0) ||
      flatDepartmentList.value.some(d => d.parentDepartmentId === dept.departmentId);
};

/**
 * 计算子部门数量
 */
const countChildDepartments = (dept) => {
  let count = 0;
  const countChildren = (d) => {
    if (d.children && d.children.length) {
      count += d.children.length;
      d.children.forEach(child => countChildren(child));
    }
  };
  countChildren(dept);
  return count;
};

/**
 * 格式化日期
 */
const formatDate = (dateString) => {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleString();
};

// 表单操作
/**
 * 重置表单
 */
const resetDeptForm = () => {
  deptForm.departmentId = '';
  deptForm.departmentName = '';
  deptForm.parentDepartmentId = 0;
  deptForm.createTime = null;
  deptForm.updateTime = null;

  if (deptFormRef.value) {
    deptFormRef.value.resetFields();
  }
};

/**
 * 打开新增部门对话框
 */
const handleAddDepartment = () => {
  resetDeptForm();
  isEditMode.value = false;
  isSubDepartment.value = false;
  currentDepartment.value = null;
  showDepartmentDialog.value = true;
};

/**
 * 打开新增子部门对话框
 */
const handleAddSubDepartment = (row) => {
  resetDeptForm();
  isEditMode.value = false;
  isSubDepartment.value = true;
  currentDepartment.value = row;
  deptForm.parentDepartmentId = row.departmentId;
  showDepartmentDialog.value = true;
};

/**
 * 打开编辑部门对话框
 */
const editDepartment = (row) => {
  resetDeptForm();
  isEditMode.value = true;
  isSubDepartment.value = false;
  currentDepartment.value = row;

  Object.assign(deptForm, {
    departmentId: row.departmentId,
    departmentName: row.departmentName,
    parentDepartmentId: row.parentDepartmentId,
    createTime: row.createTime,
    updateTime: row.updateTime
  });

  showDepartmentDialog.value = true;
};

/**
 * 保存部门（新增/编辑）
 */
const saveDepartment = async () => {
  try {
    await deptFormRef.value.validate();

    if (isEditMode.value && isChildOf(deptForm.departmentId, deptForm.parentDepartmentId)) {
      ElMessage.warning('不能选择当前部门的子部门作为上级部门');
      return;
    }

    const params = {
      departmentId: deptForm.departmentId,
      departmentName: deptForm.departmentName,
      parentDepartmentId: deptForm.parentDepartmentId
    };

    let res;
    if (isEditMode.value) {
      res = await axios.post('/api/department/update-department', params);
    } else {
      res = await axios.post('/api/department/add-department', params);
    }

    if (res.data.code === 200) {
      ElMessage.success(isEditMode.value ? '部门编辑成功' : '部门新增成功');
      showDepartmentDialog.value = false;
      await getAllDepartments();
    } else {
      ElMessage.error(res.data.msg || (isEditMode.value ? '部门编辑失败' : '部门新增失败'));
    }
  } catch (error) {
    console.error('保存部门失败：', error);
    ElMessage.error('保存部门失败，请重试');
  }
};

// 删除操作
/**
 * 打开删除确认对话框
 */
const handleDeleteConfirm = (row) => {
  currentDepartment.value = row;
  showDeleteDialog.value = true;
};

/**
 * 执行删除
 */
const deleteDepartment = async () => {
  if (!currentDepartment.value?.departmentId) return;

  try {
    const res = await axios.post('/api/department/delete-department', {
      id: currentDepartment.value.departmentId
    });

    if (res.data.code === 200) {
      ElMessage.success('部门删除成功');
      showDeleteDialog.value = false;
      await getAllDepartments();
    } else {
      ElMessage.error(res.data.msg || '部门删除失败');
    }
  } catch (error) {
    console.error('删除部门失败：', error);
    ElMessage.error('删除部门失败，请重试');
  }
};

// 对话框辅助
/**
 * 关闭对话框前的处理
 */
const handleDialogClose = (done) => {
  deptFormRef.value?.validateField(['departmentName'], (errors) => {
    if (errors.some(err => err)) {
      ElMessageBox.confirm('表单内容已修改，是否放弃保存？', '提示', {
        confirmButtonText: '放弃',
        cancelButtonText: '保留',
        type: 'warning'
      }).then(() => {
        done();
      }).catch(() => {
        // 取消关闭
      });
    } else {
      done();
    }
  });
};

// 监听与初始化
watch(searchValue, (newVal) => {
  handleSearch();
});

onMounted(async () => {
  await getAllDepartments();
});
</script>

<style scoped>
/* 基础布局样式 */
.department-manage-container {
  padding: 15px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 50px);
}

/* 页头样式 */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  flex-wrap: wrap;
  gap: 10px;
}

.breadcrumb {
  font-size: 13px;
}

.operation-bar {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 表格样式 */
.table-card {
  border-radius: 4px;
  border: 1px solid #e9ecef;
  overflow: hidden;
}

.empty-tip {
  padding: 60px 0;
  text-align: center;
}

/* 树形部门层级样式 */
.dept-tree-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  height: 36px;
}

/* 层级线样式 */
.dept-tree-wrapper::before {
  content: '';
  position: absolute;
  left: -12px;
  top: 0;
  bottom: 0;
  width: 1px;
  background-color: #dcdfe6;
}

.dept-tree-wrapper::after {
  content: '';
  position: absolute;
  left: -12px;
  top: 18px;
  width: 12px;
  height: 1px;
  background-color: #dcdfe6;
}

/* 顶级部门隐藏层级线 */
.el-table__row:first-child .dept-tree-wrapper::before,
.el-table__row:first-child .dept-tree-wrapper::after,
  /* 最后一个子部门隐藏垂直层级线 */
.el-table__row:last-child .dept-tree-wrapper::before {
  display: none;
}

.dept-name {
  flex: 1;
}

/* 操作按钮样式 */
.oper-btn {
  padding: 0 8px;
  margin: 0 2px;
}

.add-btn {
  color: #67c23a;
}

.edit-btn {
  color: #409eff;
}

.delete-btn {
  color: #f56c6c;
}

/* 表单样式 */
.dept-form {
  margin-top: 10px;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
  line-height: 1.4;
}

/* 删除提示样式 */
.delete-tip {
  padding: 10px 0;
  line-height: 1.8;
  color: #666;
}

.text-danger {
  color: #f56c6c;
  font-weight: 500;
}

.text-primary {
  color: #409eff;
  font-weight: 500;
}
</style>
